#ifndef BACKPACK_HOTSPOT_H_
#define BACKPACK_HOTSPOT_H_

#include "HotSpotVariant.hpp"
#include "Action.hpp"
#include "GameNode.hpp"
#include "Item.hpp"

#include <string>
#include <functional>

#include <boost/utility.hpp>

namespace backpack {


class GameContext;




template <class Derived>
class HotSpot : boost::noncopyable {
public:
  std::string const& getName() const {
    return m_strName;
  }
  std::string const& getDescription() const {
    return m_strDescription;
  }
  std::string const& getChoiceString() const {
    return m_strChoice;
  }
  std::string const& getLocationString() const {
    return m_strLocation;
  }
  std::string const& getLockedString() const {
    return m_strLocked;
  }

  bool hasChildHotSpot() const {
    return m_hotSpotChild != g_hotSpotNull;
  }
  HotSpotVariant const& getChildHotSpot() const {
    return m_hotSpotChild;
  }
  HotSpotVariant & getChildHotSpot() {
    return m_hotSpotChild;
  }
  void setChildHotSpot(HotSpotVariant const& hotspot) {
    m_hotSpotChild = hotspot;
  }

  void setEnabled(bool enabled) {
    m_bEnabled = enabled;
  }
  bool isEnabled() const {
    return m_bEnabled;
  }
  void setVisible(bool visible) {
    m_bVisible = visible;
  }
  bool isVisible() const {
    return m_bVisible;
  }

  bool operator==(HotSpot<Derived> const& rhs) const {
    return (this == &rhs);
  }

protected:
  HotSpot(std::string const& name, std::string const& description,
    std::string const& choiceString, std::string const& locationString,
    std::string const& lockedString)
    : m_strName(name), m_strDescription(description), m_strChoice(choiceString),
    m_strLocation(locationString), m_strLocked(lockedString),
    m_hotSpotChild(g_hotSpotNull), m_bEnabled(false), m_bVisible(true) {
  }

private:
  std::string const m_strName;
  std::string const m_strDescription;
  std::string const m_strChoice;
  std::string const m_strLocation;
  std::string const m_strLocked;
  HotSpotVariant m_hotSpotChild;
  bool m_bEnabled;
  bool m_bVisible;
}; // class HotSpot



template <class Derived>
class ActionPoint : public HotSpot<Derived> {
public:
  ActionVariant const& getAction() const {
    return m_rAction;
  }

protected:
  typedef HotSpot<Derived> Base;
  ActionPoint(std::string const& name, std::string const& description,
    std::string const& choiceString, std::string const& locationString,
    std::string const& lockedString, ActionVariant const& action)
    : Base(name, description, choiceString, locationString, lockedString),
    m_rAction(action) {
  }

private:
  ActionVariant m_rAction;
}; // class ActionPoint




class TouchPoint : public ActionPoint<TouchPoint> {
public:
  typedef ActionPoint<TouchPoint> Base;
  TouchPoint(std::string const& name, std::string const& description,
    std::string const& choiceString, std::string const& locationString,
    std::string const& lockedString, ActionVariant const& action)
    : Base(name,description,choiceString,locationString,lockedString,action) {
  }
}; // class TouchPoint



class UnlockPoint : public ActionPoint<UnlockPoint> {
public:
  typedef ActionPoint<UnlockPoint> Base;
  UnlockPoint(std::string const& name, std::string const& description,
    std::string const& choiceString, std::string const& locationString,
    std::string const& lockedString, ActionVariant const& action,
    Key const& key)
    : Base(name,description,choiceString,locationString,lockedString,action),
    m_rKey(key) {
  }
  Key const& getKey() const {
    return m_rKey;
  }

private:
  Key const& m_rKey;
}; // class UnlockPoint



class WayPoint : public HotSpot<WayPoint> {
public:
  typedef HotSpot<WayPoint> Base;
  WayPoint(std::string const& name, std::string const& description,
    std::string const& choiceString, std::string const& locationString,
    std::string const& lockedString, GameNode const& target)
    : Base(name, description, choiceString, locationString, lockedString),
    m_rTargetNode(target) {
  }
  GameNode const& getTargetNode() const {
    return m_rTargetNode;
  }

private:
  GameNode const& m_rTargetNode;
}; // class WayPoint





} // namespace backpack

#endif // BACKPACK_HOTSPOT_H_

